package com.company.hive.monitor;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 告警发送器 - 发送飞书告警
 */
public class AlertSender {
    
    private static final Logger LOG = LoggerFactory.getLogger(AlertSender.class);
    
    private final String webhookUrl;
    private final CloseableHttpClient httpClient;
    
    // 告警类型中文名称映射
    private static final Map<String, String> TYPE_NAMES = Map.of(
        "DROP_TABLE", "删除表",
        "DROP_DATABASE", "删除数据库",
        "TABLE_OVERWRITE", "表覆盖",
        "DATA_FLUCTUATION", "数据量波动",
        "BATCH_DELETE", "批量删除"
    );
    
    public AlertSender(String webhookUrl) {
        this.webhookUrl = webhookUrl;
        this.httpClient = HttpClients.createDefault();
        LOG.info("初始化告警发送器: {}", webhookUrl);
    }
    
    /**
     * 发送告警
     */
    public void send(AlertMessage alert) throws IOException {
        if (webhookUrl == null || webhookUrl.isEmpty()) {
            LOG.warn("Webhook URL未配置，跳过发送告警");
            return;
        }
        
        // 构建飞书消息卡片
        String messageJson = buildFeishuCard(alert);
        
        // 发送HTTP请求
        HttpPost httpPost = new HttpPost(webhookUrl);
        httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
        httpPost.setEntity(new StringEntity(messageJson, StandardCharsets.UTF_8));
        
        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            int statusCode = response.getStatusLine().getStatusCode();
            String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            
            if (statusCode == 200) {
                LOG.info("告警发送成功: {}", alert);
            } else {
                LOG.error("告警发送失败: statusCode={}, response={}", statusCode, responseBody);
            }
        }
    }
    
    /**
     * 构建飞书消息卡片JSON
     */
    private String buildFeishuCard(AlertMessage alert) {
        JsonObject card = new JsonObject();
        card.addProperty("msg_type", "interactive");
        
        JsonObject cardContent = new JsonObject();
        
        // 构建卡片头部
        JsonObject header = new JsonObject();
        JsonObject title = new JsonObject();
        title.addProperty("tag", "plain_text");
        title.addProperty("content", "🚨 Hive元数据告警");
        header.add("title", title);
        header.addProperty("template", alert.getLevel().getColor());
        cardContent.add("header", header);
        
        // 构建卡片内容
        JsonArray elements = new JsonArray();
        
        // 基本信息字段
        JsonObject fieldsDiv = new JsonObject();
        fieldsDiv.addProperty("tag", "div");
        
        JsonArray fields = new JsonArray();
        
        // 告警级别
        fields.add(createField(true, "**告警级别：**\n" + alert.getLevel().getName()));
        
        // 告警类型
        String typeName = TYPE_NAMES.getOrDefault(alert.getAlertType(), alert.getAlertType());
        fields.add(createField(true, "**告警类型：**\n" + typeName));
        
        // 数据库
        fields.add(createField(true, "**数据库：**\n" + alert.getDatabase()));
        
        // 表名（如果有）
        if (alert.getTable() != null && !alert.getTable().isEmpty()) {
            fields.add(createField(true, "**表名：**\n" + alert.getTable()));
        }
        
        // 操作用户（如果有）
        if (alert.getUser() != null && !alert.getUser().isEmpty()) {
            fields.add(createField(true, "**操作用户：**\n" + alert.getUser()));
        }
        
        // 操作时间
        fields.add(createField(true, "**操作时间：**\n" + alert.getFormattedTime()));
        
        fieldsDiv.add("fields", fields);
        elements.add(fieldsDiv);
        
        // 详细信息（如果有）
        if (!alert.getDetails().isEmpty()) {
            JsonObject detailsDiv = new JsonObject();
            detailsDiv.addProperty("tag", "div");
            
            JsonObject detailsText = new JsonObject();
            detailsText.addProperty("tag", "lark_md");
            
            StringBuilder detailsContent = new StringBuilder("**详细信息：**\n");
            for (Map.Entry<String, String> entry : alert.getDetails().entrySet()) {
                detailsContent.append("- ").append(entry.getKey())
                             .append(": ").append(entry.getValue()).append("\n");
            }
            
            detailsText.addProperty("content", detailsContent.toString());
            detailsDiv.add("text", detailsText);
            elements.add(detailsDiv);
        }
        
        // 分隔线
        JsonObject hr = new JsonObject();
        hr.addProperty("tag", "hr");
        elements.add(hr);
        
        // 备注
        JsonObject note = new JsonObject();
        note.addProperty("tag", "note");
        JsonArray noteElements = new JsonArray();
        JsonObject noteText = new JsonObject();
        noteText.addProperty("tag", "plain_text");
        noteText.addProperty("content", "如有疑问，请联系数据平台团队");
        noteElements.add(noteText);
        note.add("elements", noteElements);
        elements.add(note);
        
        cardContent.add("elements", elements);
        card.add("card", cardContent);
        
        return card.toString();
    }
    
    /**
     * 创建字段对象
     */
    private JsonObject createField(boolean isShort, String content) {
        JsonObject field = new JsonObject();
        field.addProperty("is_short", isShort);
        
        JsonObject text = new JsonObject();
        text.addProperty("tag", "lark_md");
        text.addProperty("content", content);
        
        field.add("text", text);
        return field;
    }
    
    /**
     * 关闭HTTP客户端
     */
    public void close() throws IOException {
        if (httpClient != null) {
            httpClient.close();
        }
    }
}

